#ifndef MOVEGENERATOR_H
#define MOVEGENERATOR_H

#include "move.h"
#include "board.h"

#include "bitutils.h"

// generate move list
class MoveGenerator
{
public:
    // constructor
    // - set reference to board
    MoveGenerator(Board & board)
        : board_(board)
    {
        qDebug() << "MoveGenerator object created";
        clearMoveList();
        initMasks();
        initAttacks();
        qDebug() << "Move generator initialised";
    }

    void clearMoveList();   
    void initMasks();
    void initAttacks();

    void generateMoves();
    size_t getCapturedPiece(size_t);
    bool isFieldAttacked(size_t, bool);
    size_t getCapturedPiece(size_t, bool);

    bool isOwnKingAttacked();
    bool isOtherKingAttacked();

    // precalculated attack patterns
    static U64 WHITE_PAWN_ATTACKS[64];
    static U64 WHITE_PAWN_MOVES[64];
    static U64 WHITE_PAWN_DOUBLE_MOVES[64];
    static U64 BLACK_PAWN_ATTACKS[64];
    static U64 BLACK_PAWN_MOVES[64];
    static U64 BLACK_PAWN_DOUBLE_MOVES[64];
    static U64 KNIGHT_ATTACKS[64];
    static U64 KING_ATTACKS[64];

    static U64 RANK_ATTACKS[64][64];      // 32KB
    static U64 FILE_ATTACKS[64][64];      // 32KB
    static U64 DIAGA8H1_ATTACKS[64][64];  // 32KB
    static U64 DIAGA1H8_ATTACKS[64][64];  // 32KB

    // Move generator 6-bit masking and magic multiplication numbers:
    static U64 RANKMASK[64];
    static U64 FILEMASK[64];
    static U64 FILEMAGICBOARD[64];
    static U64 DIAGA8H1MASK[64];
    static U64 DIAGA8H1MAGIC[64];
    static U64 DIAGA1H8MASK[64];
    static U64 DIAGA1H8MAGIC[64];

    static unsigned char SQUARE[8][8];

    void setBoard(Board & board) {
        board_ = board;
    }

    size_t getMoveListSize() {
        return moveList.size();
    }

    std::vector<Move> getMoveList() {
        return moveList;
    }

private:
    Board & board_;
    std::vector<Move> moveList;

};

#endif // MOVEGENERATOR_H
